Python requests Library

In the last lesson you learned Making HTTP Requests using the tools that ship with Python itself. They work. But the code gets long and fiddly fast. So now let me show you the friendlier way that almost every Python developer reaches for. It is the requests library.

πŸ€” Why the requests Library?

Here is the pain. Python’s built-in urllib makes you open connections by hand. You encode the data yourself. Then you decode the bytes that come back yourself too. For a simple β€œgo grab this data from a website” job, that is a lot of typing. You spend more time fighting the tool than getting your answer.

The requests library fixes that. It turns a web call into one short, readable line. You ask for a URL. You get a tidy response object back. Then you read what you need from it.

The thing is, requests is not part of Python. It is a third-party library. That means someone outside the core Python team built it, and you install it separately. So before you can use it, you install it once.

πŸ“¦ Installing requests

You install requests with pip. That is the tool that downloads Python packages. Run this in your terminal:

Terminal window
pip install requests

That downloads the library and makes it ready to import. You only do this once per environment.

Tip

If pip is not found, try pip3 install requests or python -m pip install requests. On some systems the command is spelled a little differently.

Once it is installed, you bring it into your program with a normal import:

import requests

🌐 Your First GET Request

Let me explain the word first. A GET request is you asking a server to send you something. It is like opening a web page or fetching some data. It is the most common kind of web call there is.

To make one, you call requests.get() and hand it a URL. We will use a free practice API called JSONPlaceholder. It is a fake online service that hands back sample data. It is made for exactly this kind of learning.

This code asks JSONPlaceholder for one sample post and prints what comes back:

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

Output

<Response [200]>

So what happened there?

  • requests.get(...) sent the request over the internet and waited for the reply.
  • It handed you back a response object. That is a single value that holds everything the server sent. The status, the text, the headers, all of it.
  • Printing it shows <Response [200]>. That 200 is the status code, and it means the request worked.

Note

This call goes out to a real server on the internet. So the output you see is example output. The numbers and text will be the sort of thing the server sends, but they can change over time.

πŸ”’ Reading the Status Code

Every web response comes with a status code. It is a small number that tells you how the request went, before you even look at the data.

You read it with response.status_code:

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

Output

200

You do not have to memorize all of them. But a few show up again and again:

Code Meaning In plain words
200 OK It worked, your data is here.
404 Not Found That URL points to nothing.
500 Server Error The server broke on its end, not yours.

A simple habit is to check the code before you trust the data:

import requests
response = requests.get("https://jsonplaceholder.typicode.com/posts/1")
if response.status_code == 200:
print("Request worked!")
else:
print(f"Something went wrong. Code: {response.status_code}")

Output

Request worked!

πŸ“„ Reading the Body as Text

The status code tells you if the call worked. Now you want the actual data the server sent. That part is called the response body. The plainest way to read it is response.text.

response.text gives you the body as one big string, exactly as it arrived:

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

Output

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

One thing to know here. The raw string can hold escape sequences like \n exactly as the server sent them. You read it character by character, so nothing is cleaned up for you. That is part of why .json() is the nicer choice, as you will see next.

That output looks like data. But to Python it is still just a string of characters. So if you tried to pull out the title, you could not do it cleanly yet. You would be slicing text by hand, and that is exactly the kind of work we want to avoid.

🧩 Reading JSON the Easy Way

Most modern APIs reply in a format called JSON. It is a simple text layout for data that looks a lot like Python dictionaries and lists, with keys and values. Because it is so common, requests has a one-step helper for it: response.json().

Calling response.json() reads that JSON text and turns it into a real Python dictionary. So you can grab values by their key:

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

Output

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

See the difference? Now data is a normal dictionary. data["title"] reads the title. data["userId"] reads the user id. It works just like any dictionary you have used before. No string slicing, no guessing.

Some endpoints return a list of items instead of one. This call asks for the first three posts and prints each title:

import requests
response = requests.get("https://jsonplaceholder.typicode.com/posts")
posts = response.json()
for post in posts[:3]:
print(post["title"])

Output

sunt aut facere repellat provident occaecati excepturi optio reprehenderit
qui est esse
ea molestias quasi exercitationem repellat qui ipsa sit aut

When the JSON is a list, response.json() gives you back a Python list of dictionaries. So you loop over it the same way you loop over any list.

Note

response.text and response.json() read the same body. .text gives you the raw string. .json() parses that string into Python objects. Reach for .json() whenever the server sends JSON, which is most of the time.

⚠️ Common Mistakes

A few things trip people up early on:

  • Forgetting to install it. requests is third-party. If you see ModuleNotFoundError: No module named 'requests', you skipped the pip install requests step.

  • Calling .json instead of .json(). It is a method, so it needs the parentheses. Without them you get the method itself, not the data.

# ❌ Avoid: forgets the parentheses, this does not parse anything
data = response.json
# βœ… Good: calls the method and gets a dictionary back
data = response.json()
  • Trusting the data without checking the code. If the request returned a 404 and you call .json() anyway, you may get an error or empty data. Check status_code first.

  • Calling .json() on a non-JSON page. If you point requests at a normal web page, the body is HTML, not JSON. Calling .json() on it raises an error. Use .text for those.

βœ… Best Practices

Small habits that keep your API code calm and predictable:

  • Check response.status_code before you read the body. That way a failed call does not crash your program later.
  • Use .json() when the server sends JSON, and .text when you just want the raw string.
  • Save the result of response.json() into a variable once instead of calling it again and again.
  • Keep URLs in a named variable when they get long, so your call line stays easy to read.

🧩 What You’ve Learned

βœ… requests is a third-party library you install with pip install requests.

βœ… requests.get(url) sends a GET request and returns a response object.

βœ… response.status_code tells you if the call worked, with 200 meaning success.

βœ… response.text gives the body as a raw string.

βœ… response.json() parses JSON into a Python dictionary or list so you can read values by key.

Check Your Knowledge

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

  1. 1

    Why do you need to run 'pip install requests' before using it?

    Why: requests is not part of the Python standard library, so you install it separately with pip.

  2. 2

    What does a status code of 200 mean?

    Why: 200 means OK, the request succeeded and your data is in the response.

  3. 3

    What does response.json() return when the server sends a JSON object?

    Why: response.json() parses the JSON body into Python objects, an object becomes a dictionary.

  4. 4

    What is the difference between response.text and response.json()?

    Why: .text is the body as a plain string; .json() parses that same body into a dictionary or list.

πŸš€ What’s Next?

Now that you can fire off a request and read the reply, let’s slow down and look closely at the most common call of all and everything you can do with it.

GET Requests

Share & Connect