Courseiva
200-901Chapter 10 of 18Objective 1.4

Using Python Requests to Interact with APIs

Without the ability to make automated requests to remote servers, every single piece of data you want from a web service would require you to manually open a browser, click around, and copy-paste results by hand. That is slow, error-prone, and impossible at scale. For the 200-901 exam, you must master the Python Requests library because it is the most common tool used by network automation engineers to talk to REST APIs, and the exam will test your ability to write, send, and handle these requests programmatically.

12 min read
Intermediate
Updated Jul 23, 2026
Reviewed by Johnson Ajibi· Senior Network & Security Engineer · MSc IT Security

A simple way to picture Using Python Requests to Interact with APIs

The 14-Course Tasting Menu Analogy

You are at a high-end restaurant that offers a 14-course tasting menu. You do not walk into the kitchen to cook the food yourself. Instead, you sit at your table, open the menu, and decide what you want. Each request you make to the waiter is a specific, polite instruction: 'Please bring me the third course now.' The waiter does not argue, ask why, or bring the entire kitchen. The waiter writes your request on a small pad, walks to the kitchen, and returns with exactly what you asked for. In this analogy, you are the Python application. The menu is the API documentation. The waiter is the Python Requests library. The kitchen is the remote server that holds the data. The physical plate of food that arrives is the response from the server. You never touch the kitchen. You never see how the chef chops the carrots. You simply make a request, and the answer comes back. If you ask for course seven before course one, the waiter will tell you that the kitchen cannot do that — that is a 400-level error code. If you ask for something that does not exist on the menu, the waiter returns empty-handed — a 404 response. The whole interaction relies on a shared menu and a shared language of polite requests. You do not need to know whether the kitchen uses gas or induction hobs. All you need to know is how to read the menu and how to ask politely.

How It Actually Works

The Python Requests library is a tool that allows your Python script to communicate with web servers using the HTTP protocol. HTTP stands for HyperText Transfer Protocol. It is the same language your web browser uses when you visit a website. The Requests library gives you a simple way to send HTTP requests from Python without needing to manually handle network sockets or parse complicated raw data.

To understand Requests, you must first understand a REST API. REST stands for Representational State Transfer. An API is an Application Programming Interface — it is a set of rules that allows one piece of software to talk to another. A REST API is a specific type of API that uses standard HTTP methods to perform operations on data. The four most common HTTP methods are GET, POST, PUT, and DELETE. A GET request retrieves data. A POST request creates new data. A PUT request updates existing data. A DELETE request removes data.

Every request you send has a few key parts. The first is the URL, which stands for Uniform Resource Locator. This is the address of the resource you want to interact with, exactly like a website address. The second is headers, which are additional pieces of information sent alongside your request, such as authentication credentials or the format of data you expect. The third is the body, which contains data you want to send to the server, usually in JSON format. JSON stands for JavaScript Object Notation — it is a lightweight text format for storing and transporting data, and it looks like a dictionary with keys and values.

When you use the Requests library, you start by importing it with the line 'import requests'. Then you call a function that matches the HTTP method you need. For a GET request, you write 'response = requests.get(url)'. For a POST request, you write 'response = requests.post(url, json=data)'. The variable 'response' now holds a Response object, which contains everything the server sent back. You can access the status code with 'response.status_code'. A status code is a three-digit number that tells you whether the request succeeded. Codes in the 200 range mean success. 200 means 'OK'. 201 means 'Created'. Codes in the 400 range mean the client made a mistake. 404 means 'Not Found'. Codes in the 500 range mean the server had an error.

To get the data the server returned, you use 'response.json()' if the response is in JSON format. This method parses the JSON string and converts it into a Python dictionary or list, which you can then work with in your code. You can also see the raw text with 'response.text'. Additionally, you can check the headers the server sent back with 'response.headers'.

Why does this library exist? Before libraries like Requests, developers had to use lower-level modules like 'urllib' or 'httplib', which required many more lines of code to handle cookies, redirects, and authentication. Requests simplifies all of this into one or two lines of code. It automatically handles many common tasks, such as encoding parameters, following redirects, and keeping connections alive. This makes your code cleaner, more readable, and less prone to errors.

Flow of a typical Python script using the Requests library to send a GET request to a REST API and handle the response.

Walk-Through

1

Import the Requests library

Write 'import requests' at the top of your Python file. This makes all the Requests functions available to your code. Without this line, Python will not know what 'requests.get' means and will throw a NameError.

2

Define the target URL

Assign the API endpoint URL to a variable, for example 'url = "https://api.example.com/devices"'. The URL is the address of the resource you want to interact with. Make sure it is a string inside quotation marks.

3

Set up headers and authentication

Create a dictionary for headers, for example 'headers = {"Authorization": "Bearer my_token"}'. Many APIs require a token or API key to verify your identity. You pass this dictionary to the 'headers' argument in the request function.

4

Send the HTTP request and capture the response

Call the appropriate Requests function, such as 'response = requests.get(url, headers=headers)' for a GET request. The function sends the request over the internet and waits for the server to reply. The returned 'response' object contains everything the server sent back.

5

Inspect the response status code

Check 'response.status_code' to see if the request succeeded. A status code of 200 means 'OK', 404 means 'Not Found', and 500 means 'Internal Server Error'. You should write conditional logic to handle different status codes, such as printing an error message if the code is not 200.

6

Extract and use the response data

If the response body is in JSON format, call 'data = response.json()' to convert the JSON string into a Python dictionary or list. You can now loop through the data, print it, or store it in a file. If the body is plain text, use 'response.text' instead.

What This Looks Like on the Job

A network engineer at a company called CloudNet Solutions needs to automate the management of 200 network switches spread across three data centres. Each switch is a Cisco device that runs a REST API. The engineer, Priya, wants to write a Python script that checks the health status of every switch every five minutes. Without the Requests library, Priya would have to manually SSH into each switch, run a command, and parse the output. That would take hours and be highly error-prone.

Priya writes a Python script using the Requests library. Her script uses a GET request to the endpoint '/api/v1/health' on each switch. The URL for one switch looks like 'https://10.0.1.1/api/v1/health'. She also sends a header containing an API token for authentication. The API token is a secret string that proves her script has permission to access the switch. She writes a simple loop that iterates over a list of IP addresses, sends a GET request to each one, and then checks the status code. If the status code is 200, she parses the JSON response with 'response.json()' and extracts the uptime and CPU load. If the status code is anything else, she logs the IP address and the error code to a file.

Later, Priya needs to push a new configuration to 50 of those switches. She uses a POST request. She constructs a JSON payload containing the new configuration details. The JSON payload is a dictionary with keys like 'vlan_id', 'interface', and 'description'. She sends the request with 'requests.post(url, json=payload, headers=headers)'. The server responds with a 201 status code if the configuration was applied successfully, or with a 400 status code if the JSON was malformed.

Priya's script runs continuously. It saves her team roughly 20 hours of manual work per week. It also reduces human error because the script checks every response for errors and retries failed requests. In an interview, Priya would explain that the Requests library is the backbone of her automation because it allows her to treat network devices as programmable resources rather than physical boxes she has to log into.

How 200-901 Actually Tests This

The 200-901 exam tests your practical ability to use the Python Requests library. Expect multiple-choice questions that show you a short code snippet and ask you what the output will be, which method to use, or what a specific attribute means. The exam does not ask you to memorise the entire Requests library documentation, but it does expect you to know the core functions and common pitfalls.

The exam loves to test the following concepts:

The difference between GET, POST, PUT, and DELETE. You must know which method is idempotent (GET and PUT are idempotent, meaning repeated calls produce the same result) and which is not (POST is not idempotent).

How to pass query parameters. A common question will display a URL and ask which argument in the 'requests.get()' call passes parameters. The correct answer is the 'params' keyword argument, not appending them manually to the URL string.

How to send JSON data. The exam will ask whether you use the 'data' argument or the 'json' argument with 'requests.post()'. The correct answer is 'json' when you want the library to automatically serialise your Python dictionary and set the Content-Type header to 'application/json'.

How to read the status code and the response body. Questions often ask what 'response.status_code' returns (an integer) and what 'response.json()' returns (a Python dictionary or list).

Traps the exam sets include:

Confusing the 'json' argument with the 'data' argument. If you use 'data' with a dictionary, the library will URL-encode it by default, not send it as JSON.

Forgetting that 'response.json()' can raise an exception if the response body is not valid JSON. The exam may ask what happens if you call '.json()' on a 404 response that returns an HTML page.

Not recognising that a 200 status code does not guarantee the data is correct — it only means the request was processed. The actual business logic might still have failed.

Key definitions to memorise:

HTTP methods: GET (read), POST (create), PUT (update/replace), DELETE (remove).

Status code ranges: 2xx success, 4xx client error (bad request, unauthorised, not found), 5xx server error.

Requests library import: 'import requests'.

Common response attributes: 'status_code', 'text', 'json()', 'headers'.

Key Takeaways

The Python Requests library sends HTTP requests (GET, POST, PUT, DELETE) to REST APIs and returns a Response object.

Use the 'json' argument in POST and PUT requests to automatically serialise a Python dictionary and set the correct Content-Type header.

Always check the status code with 'response.status_code' to determine whether the server processed the request successfully.

The 'params' argument is the correct way to add query parameters to a URL in a GET request, not string concatenation.

Calling 'response.json()' parses the response body as JSON and returns a Python data structure, but it raises an exception if the body is not valid JSON.

A 4xx status code means the client made an error (like a bad request or unauthorised access), while a 5xx status code means the server encountered an error.

Import the Requests library at the top of your script with 'import requests' before using any of its functions.

The Response object contains all the information from the server, including headers, status code, and the body content.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

GET request

Retrieves data from a server without changing anything

Idempotent — calling it multiple times gives the same result

Passes parameters in the URL or via the 'params' argument

POST request

Creates new data on the server

Not idempotent — calling it multiple times can create multiple resources

Passes data in the request body, usually as JSON via the 'json' argument

response.json()

Parses the response body as JSON and returns a Python data structure

Raises a JSONDecodeError if the body is not valid JSON

Automatically handles encoding based on the Content-Type header

response.text

Returns the raw response body as a string

Works even if the body is not JSON (e.g., HTML or plain text)

You must manually decode or parse the string yourself

Status code 200

Means the request succeeded and the response contains data

Often used for GET requests that return a resource

Does not imply a new resource was created

Status code 201

Means the request succeeded and a new resource was created

Most commonly returned by POST requests

Often includes a 'Location' header with the URL of the new resource

requests.get() with params

Automatically URL-encodes special characters in parameter values

Keeps code clean and readable

Less error-prone when parameters are dynamic

Manually building URL with query string

Requires manual handling of URL encoding

More prone to errors like missing question marks or ampersands

Can be useful for simple, static URLs

Watch Out for These

Mistake

You need to install the Requests library separately for every Python project you create.

Correct

You install the library once in your Python environment (like a virtual environment) and import it in any script that runs in that environment.

Beginners confuse module installation with project configuration, especially if they have used JavaScript npm where dependencies are per project.

Mistake

The 'response.json()' method always returns a Python dictionary.

Correct

It returns whatever JSON structure the server sends, which could be a list, a string, a number, or a dictionary.

Many tutorial examples show JSON objects (dictionaries), so learners assume that is the only possible type, but JSON arrays (lists) are equally common.

Mistake

If a request returns a 200 status code, the data in the response is definitely the data you wanted.

Correct

A 200 status code only means the server processed the request successfully; the data could still contain an error message or a null value if the business logic failed.

People transfer their understanding of a web page loading successfully (200 means the page is there) to API responses, where 200 is just a transport-level success, not a logic-level one.

Mistake

Using 'requests.post(url, data=my_dict)' sends the data as JSON.

Correct

It sends the data as form-encoded data by default. To send JSON, you must use the 'json' argument instead of 'data'.

The word 'data' sounds generic enough to mean 'the content you are sending', so beginners naturally assume it works for all formats.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

What is the difference between the 'data' and 'json' arguments in requests.post()?

The 'data' argument sends the data as form-encoded (like a web form submission). The 'json' argument automatically converts a Python dictionary to a JSON string and sets the Content-Type header to 'application/json'. For REST APIs, you almost always want to use 'json'.

What does response.json() return if the server returns an empty body?

Calling response.json() on an empty body raises a 'json.decoder.JSONDecodeError' because an empty string is not valid JSON. Always check the status code or the length of response.text before calling .json() to avoid this error.

How do I pass query parameters like ?page=2&limit=10 in a GET request?

Use the 'params' argument with a dictionary. For example, 'requests.get(url, params={"page": 2, "limit": 10})'. The library automatically constructs the correct URL string for you.

What do I do if the API requires authentication?

Most APIs require an API key or a bearer token sent in the HTTP headers. Create a headers dictionary like '{"Authorization": "Bearer YOUR_TOKEN"}' and pass it to the 'headers' argument in the request.

Why am I getting a 401 status code when I use the Requests library?

A 401 status code means 'Unauthorized'. This usually means your authentication token is missing, expired, or incorrect. Double-check the token value and make sure you are sending it in the correct header format that the API expects.

Can I use the Requests library without an internet connection?

The Requests library sends HTTP requests over a network, so you need an active internet connection (or at least a network connection to the server) to use it. You cannot use it for purely local operations.

Terms Worth Knowing

Keep going

You've finished Using Python Requests to Interact with APIs. Continue through the 200-901 study guide to build a complete picture of the exam.

Done with this chapter?