Skip to content

API Testing with Python Requests

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about API Testing with Python Requests. We cover key concepts, practical examples, and best practices to help you master this topic.

The Python requests library is a simple yet powerful HTTP client for API testing. It provides session objects for connection reuse, built-in authentication, file upload support, and integration with pytest for structured test suites.

What You'll Learn

  • Session management for connection reuse
  • Authentication methods (Basic, Bearer, custom)
  • File uploads and multipart forms
  • Retry and timeout configuration
  • Response validation patterns

Why It Matters

Requests is the most popular Python HTTP library. It is readable, well-documented, and works seamlessly with pytest. Understanding requests is essential for any Python API tester.

Real-World Use

The requests library is used by the Python community for all HTTP interactions. Many test automation frameworks are built on top of requests. It is the standard for API testing in Python.

flowchart LR
    Test[Test Code] --> Session[requests.Session]
    Session --> Auth[Auth Setup]
    Session --> Headers[Default Headers]
    Session --> Retry[Retry Config]
    Session --> Request[HTTP Request]
    Request --> Response[Response]
    Response --> Assert[Assertions]

Teacher Mindset

Use sessions for connection pooling and default configuration. Set auth and headers once on the session. Use response objects for status, headers, and body inspection.

Code Examples

# Example 1: Session-based API testing
import requests
from requests.auth import HTTPBasicAuth

class APIClient:
    def __init__(self, base_url):
        self.session = requests.Session()
        self.base_url = base_url
        self.session.headers.update({
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        })

    def authenticate(self, username, password):
        response = self.session.post(
            f"{self.base_url}/auth/login",
            json={"username": username, "password": password}
        )
        token = response.json()["token"]
        self.session.headers.update({
            'Authorization': f'Bearer {token}'
        })
        return token

    def get_users(self):
        response = self.session.get(f"{self.base_url}/api/users")
        response.raise_for_status()
        return response.json()
# Example 2: File upload and error handling
import requests

def test_file_upload():
    with open('test_data/document.pdf', 'rb') as f:
        response = requests.post(
            'http://api/files/upload',
            files={'file': ('document.pdf', f, 'application/pdf')},
            headers={'Authorization': f'Bearer {token}'}
        )

    assert response.status_code == 201
    data = response.json()
    assert 'file_id' in data
    assert data['filename'] == 'document.pdf'

def test_error_handling():
    response = requests.get('http://api/users/999')
    assert response.status_code == 404

    error = response.json()
    assert 'error' in error
    assert error['error'] == 'User not found'
# Example 3: Retry and timeout configuration
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

def create_resilient_session():
    session = requests.Session()

    retries = Retry(
        total=3,
        backoff_factor=0.5,
        status_forcelist=[500, 502, 503, 504]
    )

    adapter = HTTPAdapter(max_retries=retries)
    session.mount('http://', adapter)
    session.mount('https://', adapter)

    return session

session = create_resilient_session()
response = session.get(
    'http://api/products',
    timeout=(3.05, 15),
    params={'page': 1, 'limit': 20}
)

Common Mistakes

  • Creating a new session for every request instead of reusing one
  • Not calling raise_for_status() to detect HTTP errors
  • Hardcoding tokens instead of using sessions with automatic auth
  • Not setting reasonable timeouts, causing hung tests
  • Ignoring SSL verification in production tests

Practice

  1. Create an API client class using requests.Session with base URL and auth.
  2. Write tests for CRUD operations using the session.
  3. Test file upload with multipart form data.
  4. Implement retry logic for transient failures.
  5. Challenge: Build a test framework that wraps requests with logging, timing, and reporting.

FAQ

What is the difference between requests and httpx?

requests is sync-only and more widely used. httpx supports both sync and async, HTTP/2, and is newer.

How do I handle authentication in requests?

Use auth parameter (Basic, Digest), session.headers for Bearer tokens, or custom auth classes.

What is raise_for_status()?

It raises HTTPError if the response status code indicates an error (4xx or 5xx).

How do I send JSON data?

Use the json parameter: requests.post(url, json={'key': 'value'}). This sets Content-Type automatically.

Can I use requests with async Python?

requests is sync-only. Use httpx for async HTTP requests.

Mini Project

Build a Python test framework using requests for a REST API. Create a session-based APIClient class with authentication. Write tests for CRUD operations, file upload, error handling, and pagination. Include retry logic and timeout configuration.

What's Next

Next, you will learn about REST Assured for testing Java APIs.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro