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.
Jump to a section
A simple way to picture Using Python Requests to Interact with APIs
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.
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.
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.
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.
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.
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.
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.
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.
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.
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'.
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.
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
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.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
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'.
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.
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.
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.
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.
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.
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?