Python GET Requests

In the last lesson you set up the requests Library and saw how it lets your Python code talk to the internet. Now we put it to work. The most common thing you will ever do with an API is ask it for some data. That is what a GET request is for.

πŸ€” Why GET Requests?

Say you are building a small app. You need a list of users. Or some posts. Or the current weather. That data lives on someone else’s server, not on your machine. So how do you get it into your program?

You ask for it. A GET request is your program saying to a server: β€œplease send me this data.” The server reads what you asked for and sends it back.

There is one key thing to remember. GET only reads. It never changes anything on the server. You can run the same GET request a hundred times and the server stays exactly the same. Think of it like reading a page on Wikipedia. You can open it again and again. Just looking at it does not edit the page.

🧩 What a GET Request Looks Like

A test API is a free server made for practice. It gives you fake but realistic data so you can learn without breaking anything real. We will use JSONPlaceholder, a popular free one.

First make sure requests is installed. It is a third-party library, so it does not come with Python by default. Run this in your terminal:

Terminal window
pip install requests

Here is the simplest GET request you can write. It asks JSONPlaceholder for a single post.

import requests
response = requests.get("https://jsonplaceholder.typicode.com/posts/1")
print(response.status_code)
print(response.text)

Let me walk through it line by line:

  • import requests brings in the library so we can use it.
  • requests.get(...) sends the GET request to that web address and waits for the reply. The reply is stored in a variable we called response.
  • response.status_code is a number the server sends back to say how it went. A status code of 200 means success.
  • response.text is the raw reply as plain text.

This is the kind of thing it prints. The data comes from the internet, so this is example output. Yours may look slightly different.

Output

200
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}

That 200 tells us the request worked. The block after it is the post the server sent back.

πŸ“¦ Reading JSON with response.json()

The reply above looks like a Python dictionary, but it is not yet. As response.text it is just a long string of characters. You cannot pull a value out of a string by key.

JSON is the common text format APIs use to send data. It looks almost exactly like Python dictionaries and lists. The requests library can turn that JSON text into real Python objects for you with one method: response.json().

Here we fetch the same post and read it as proper Python data:

import requests
response = requests.get("https://jsonplaceholder.typicode.com/posts/1")
post = response.json()
print(type(post))
print(post["title"])
print(post["userId"])

What is happening here:

  • response.json() reads the JSON reply and gives you back a real Python dict.
  • We store that dict in post.
  • Now we can grab values by key, just like any dictionary. So post["title"] works.

This is the example output:

Output

<class 'dict'>
sunt aut facere repellat provident occaecati excepturi optio reprehenderit
1

See the difference? type(post) shows dict, not str. That means we can now use normal dictionary tools on the data.

Tip

Use response.text when you want the raw reply, and response.json() when the API sends JSON and you want to work with the values. For almost every API, you want response.json().

πŸ”Ž Sending Query Parameters with params

Often you do not want everything. You want a filtered slice. Like β€œonly the posts written by user number 1.” You tell the server what you want by adding query parameters to the request.

Query parameters are little key-and-value pairs that get attached to the end of the web address after a ?. You could type them by hand into the address, but that gets messy and easy to break. The clean way is to pass a dictionary to params.

Here we ask only for the posts that belong to user 1:

import requests
response = requests.get(
"https://jsonplaceholder.typicode.com/posts",
params={"userId": 1}
)
print(response.url)
posts = response.json()
print(len(posts))

The important parts:

  • params={"userId": 1} is the filter. requests takes that dictionary and builds the full address for you.
  • response.url shows the final address that was actually requested, so you can see what params did.
  • posts is now a list of dictionaries, one dictionary per post.
  • len(posts) counts how many posts came back.

This is the example output:

Output

https://jsonplaceholder.typicode.com/posts?userId=1
10

Notice how requests glued ?userId=1 onto the address for you. You wrote a clean dictionary and let the library handle the formatting. That is much safer than building the string yourself.

Note

When the API returns one item (like /posts/1), response.json() gives you a dict. When it returns many items (like /posts), it gives you a list of dicts. Check which one you have before you use it.

πŸ” Looping Over the Results

Once you have a list back, you almost always want to go through it item by item. A normal for loop does the job, since the result is just a regular Python list.

Here we fetch user 1’s posts and print the title of each one:

import requests
response = requests.get(
"https://jsonplaceholder.typicode.com/posts",
params={"userId": 1}
)
posts = response.json()
for post in posts:
print(f"Post {post['id']}: {post['title']}")

Reading the loop:

  • posts is the list of post dictionaries we got back.
  • The for loop hands us one post dictionary at a time.
  • Inside, post['id'] and post['title'] pull values out of that single post.

This is the example output, trimmed to the first few lines:

Output

Post 1: sunt aut facere repellat provident occaecati excepturi optio reprehenderit
Post 2: qui est esse
Post 3: ea molestias quasi exercitationem repellat qui ipsa sit aut
Post 4: eum et est occaecati
Post 5: nesciunt quas odio

That is the full pattern most API code follows. Send a GET. Read the JSON. Loop the results. Once this clicks, a lot of real-world Python opens up to you.

⚠️ Common Mistakes

A few things trip people up early on:

  • Forgetting to call .json() and trying to index the raw text. You cannot do response["title"] on a string.
# ❌ Avoid: response is a Response object, not the data
title = response["title"]
# βœ… Good: turn it into Python data first
data = response.json()
title = data["title"]
  • Building the query string by hand instead of using params. It is easy to forget a ? or an &, or to leave a space in.
# ❌ Avoid: messy and easy to break
response = requests.get("https://jsonplaceholder.typicode.com/posts?userId=1")
# βœ… Good: let requests build it safely
response = requests.get(
"https://jsonplaceholder.typicode.com/posts",
params={"userId": 1}
)
  • Assuming you always get a list. A request for one item gives a single dict, so looping over it loops over its keys, not what you expect.
  • Ignoring the status code. If the request failed, response.json() may not contain the data you assume. Check response.status_code first when something looks off.

βœ… Best Practices

Small habits that keep your API code clean:

  • Use params={...} for query parameters instead of typing them into the address yourself.
  • Reach for response.json() whenever the API returns JSON, then treat the result as a normal dict or list.
  • Check response.status_code (or print response.url) while you are still figuring out a new API.
  • Remember that GET only reads. If you ever want to send or change data on the server, that is a different kind of request, not GET.

🧩 What You’ve Learned

βœ… A GET request asks a server for data and only reads. It never changes anything on the server.

βœ… requests.get(url) sends the request and gives you back a Response object.

βœ… response.json() turns the JSON reply into real Python dicts and lists you can use.

βœ… params={...} adds query parameters so you can ask for a filtered slice of the data.

βœ… When the result is a list, a plain for loop lets you go through each item.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    What does a GET request do on the server?

    Why: GET is read-only. Running the same GET request again does not change anything on the server.

  2. 2

    Why use response.json() instead of response.text?

    Why: response.text is a plain string, while response.json() parses the JSON into Python objects so you can access values by key.

  3. 3

    What is the cleanest way to send query parameters with requests?

    Why: Passing params={...} lets requests build the query string safely instead of you formatting it by hand.

  4. 4

    When an API endpoint like /posts returns many items, what does response.json() usually give you?

    Why: Endpoints that return many items give back a list of dicts, so a normal for loop works over them.

πŸš€ What’s Next?

You can now read data from any API. The next step is sending data the other way, creating something new on the server.

POST Requests

Share & Connect