#3 - API Testing with requests
What Really Happens When You Call requests.get() API Testing using requests and pytest
• Possess over 14 years of experience in Quality Engineering, specializing in building test frameworks for complex systems including web applications, REST APIs, and core cloud infrastructure on platforms like Akamai's Linode and Azure.
• Skilled in the development and improvement of automation frameworks for various Web applications, service APIs displaying proficiency in TestNG, PyTest, Selenium, Rest Assured, Jenkins pipeline.
Python requests Module
requests is a high-level HTTP client for Python that lets you talk to APIs using simple, readable code instead of low-level networking.
What Really Happens When You Call requests.get()
Below is get call with params - requests.get() is wrapper to make HTTP GET call
response = requests.get(url="https://gorest.co.in/public/v2/users", params={"page":2})
Below is behind the scene calls for above get() call

Internally this calls requests.api.request()
requests.api.get(url)
↓
requests.api.request("GET", url, **kwargs)
A temporary session is created
A new Session object is created
It exists only for this single request
It is managed using a context manager
It is automatically closed after the request completes
with sessions.Session() as session:
...
A Request Object Is Built
req = Request(
method="GET",
url="https://gorest.co.in/public/v2/users",
params={"page": 2}
)
The Request Is Prepared
Query params are URL-encoded
?page=2 is appended to the URL
Headers are merged and normalized
Default headers like User-Agent are added
Body (if any) is serialized
prepared_req = session.prepare_request(req)
The Prepared Request Is Sent
DNS lookup happens
TCP connection is opened
TLS handshake occurs (for HTTPS)
HTTP request bytes are sent
Server response is received
response = session.send(prepared_req)
A Response Object Is Created
Once the server replies, requests build a Response object.
Status code
Response headers
Raw response body
Timing information
Helper methods like .json()
The Session Is Closed Automatically
with Session() as session:
Once the response is returned:
The session is closed
Connections are released
API Testing using requests and pytest
In this section will use requests module to make API requests, process response, add assertion and execute using pytest.
Setup variables
BASE_URL = "https://gorest.co.in/public/v2"
USERS_ENDPOINT = f"{BASE_URL}/users"
USER_ENDPOINT = f"{USERS_ENDPOINT}/{{user_id}}"
TOKEN = os.environ.get("API_TOKEN")
headers = {"Authorization": f"Bearer {TOKEN}"}
Create User Flow
Using Faker to create unique user data support for multiple execution
Created user payload using Python dictionary but API doesn’t understand Python dictionary
Requests module convert python dictionary to JSON string using json.dumps(create_user_payload) before sending request and also append header as Content-Type: application/json→ Serialization
To process the response body we need to convert response bytes to Python dictionary → deserialization
- Using response_body = response.json() which internally calls json.loads(decoded_response_text)
def test_create_user():
# Create unique data for multiple execution
fake = Faker()
username = fake.name_male()
user_email = fake.email()
user_gender = "male"
user_status = "inactive"
# create user payload as python dict
create_user_payload = {
"name": username,
"email": user_email,
"gender": user_gender,
"status": user_status
}
# send POST request
response = requests.post(url= USERS_ENDPOINT, headers= headers, json= create_user_payload)
response_body = response.json()
print(f"Status Code: {response.status_code}")
print(f"Response Body: {response_body}")
# Assertion
assert response.status_code == 201
assert response_body["name"] == username
assert response_body["email"] == user_email
assert response_body["gender"] == user_gender
assert response_body["status"] == user_status
Execute the test using pytest and uv
uv run pytest -s tests/test_gorest_crud.py::test_create_user

Test execution using pytest and uv
Rest of test can be found here → https://github.com/sksingh329/gorest-api-test/blob/basics/gorest-crud/tests/test_gorest_crud.py
# Check uv is installed
uv --version
# Clone the repo
git clone https://github.com/sksingh329/gorest-api-test.git
# Switch to directory and branch
cd gorest-api-test
git switch basics/gorest-crud
# Install required package
uv sync
# Export token
export API_TOKEN=<replace with your token>
# Run specific test
uv run pytest -s tests/test_gorest_crud.py::test_create_user
# Run all tests
uv run pytest
In this section, we used requests to make API calls and pytest to execute tests. This approach works well for basic testing, but it doesn’t scale. To build a maintainable and scalable test suite, we need shared utilities—such as requests.Session, pytest fixtures via conftest.py, and structured HTML reporting—which will be covered in upcoming articles.
